import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class StaggerAnimation extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _StaggerAnimationState();
  }
}

class _StaggerAnimationState extends State<StaggerAnimation>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  var _animationState;
  var _images = [
    'index.jpg',
    'index2.jpg',
    'index3.jpg',
    'index4.jpg',
    'index55.jpg'
  ];
  var _count = 0;
  var _isShowFirst = true;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _animationController =
        AnimationController(duration: Duration(seconds: 3), vsync: this);
    _animationController.addStatusListener((state) {
      switch (state) {
        case AnimationStatus.dismissed:
          // TODO: Handle this case.
          print(AnimationStatus.dismissed.toString());
          _animationState = AnimationStatus.dismissed;
          break;
        case AnimationStatus.forward:
          // TODO: Handle this case.
          print(AnimationStatus.forward.toString());
          break;
        case AnimationStatus.reverse:
          // reverse
          print(AnimationStatus.reverse.toString());
          break;
        case AnimationStatus.completed:
          // TODO: Handle this case.
          print(AnimationStatus.completed.toString());
          _animationState = AnimationStatus.completed;
          break;
      }
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _animationController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('交织动画'),
      ),
      body: GestureDetector(
        onTap: () {
          if (_animationState == AnimationStatus.completed) {
            _animationController.reverse();
          } else {
            _animationController.forward();
          }

          setState(() {
            if (_count == 4) {
              _count = 0;
            } else {
              _count++;
            }
            _isShowFirst = !_isShowFirst;
            print(_count);
          });
        },
        child: Center(
          child: Column(
            children: <Widget>[
              Container(
                alignment: Alignment.center,
                width: 200,
                height: 200,
                decoration: BoxDecoration(
                  color: Colors.black.withOpacity(0.1),
                  border: Border.all(
                    color: Colors.black.withOpacity(0.5),
                  ),
                ),
                child: Stagger(_animationController),
              ),
              GestureDetector(
                  child: AnimatedSwitcher(
                duration: Duration(milliseconds: 500),
                transitionBuilder: (child, anmited) {
                  var teew = Tween(begin: Offset(1,0),end: Offset(0,0)).animate(anmited);
                  return MySlideTransition(
                    position: teew,
                    child: child,
                  );
                },
                child: Container(
                  key: ValueKey(_count),
                  width: 200,
                  height: 200,
                  decoration: BoxDecoration(
                      color: Colors.black.withOpacity(0.1),
                      border: Border.all(color: Colors.black.withOpacity(0.5))),
                  child: Image.asset(_images[_count], fit: BoxFit.cover),
                ),
              )),
              GestureDetector(
                child: AnimatedCrossFade(
                  firstChild: Image.asset(
                    _images[0],
                    width: 200,
                    height: 200,
                  ),
                  secondChild: Image.asset(
                    _images[1],
                    width: 200,
                    height: 200,
                  ),
                  duration: Duration(seconds: 2),
                  crossFadeState: _isShowFirst
                      ? CrossFadeState.showFirst
                      : CrossFadeState.showSecond,
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

class MySlideTransition extends AnimatedWidget {
  MySlideTransition(
      {Key key, Animation<Offset> position, this.transformHitTests, this.child})
      : assert(position != null),
        super(key: key, listenable: position);

  Animation<Offset> get position => listenable;
  final bool transformHitTests;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    Offset offset = position.value;
    if (position.status == AnimationStatus.reverse) {
      offset = Offset(-offset.dx, offset.dy);
    }
    // TODO: implement build
    return FractionalTranslation(
      translation: offset,
      child: child,
    );
  }
}

class Stagger extends StatelessWidget {
  Stagger(this.controller) {
    height = Tween<double>(begin: 0, end: 200).animate(CurvedAnimation(
        parent: controller, curve: Interval(0.0, 0.6, curve: Curves.ease)));
    color = ColorTween(
      begin: Colors.green,
      end: Colors.red,
    ).animate(CurvedAnimation(
        parent: controller,
        curve: Interval(0.0, 0.6, curve: Curves.easeInCirc)));
    padding = Tween<EdgeInsets>(
            begin: EdgeInsets.only(left: 0.0), end: EdgeInsets.only(left: 300))
        .animate(CurvedAnimation(
            parent: controller,
            curve: Interval(0.4, 1.0, curve: Curves.bounceIn)));
  }

  final Animation<double> controller;
  Animation<double> height;
  Animation<EdgeInsets> padding;
  Animation<Color> color;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return AnimatedBuilder(
      animation: controller,
      builder: (context, child) {
        return Container(
          alignment: Alignment.bottomCenter,
          padding: padding.value,
          child: Container(
            width: 10,
            height: height.value,
            color: color.value,
          ),
        );
      },
    );
  }
}
